﻿using System;
using System.Threading;
using static System.Threading.Thread;
using static System.Console;

namespace Project_2
{
    /// <summary>
    /// 2.2 线程原子操作
    /// </summary>
    public class Unit_2_02
    {
        /*
         * Interlocked 类为多线程共享变量提供一些原子操作，
         * 一些数字操作可以使用这个类的方法
         */
        public static void Go()
        {
            WriteLine("不准确的计数器开始...");
            var c=new Counter();

            var t1=new Thread(()=>TestCounter(c));
            var t2 = new Thread(() => TestCounter(c));
            var t3 = new Thread(() => TestCounter(c));

            t1.Start();
            t2.Start();
            t3.Start();

            t1.Join();
            t2.Join();
            t3.Join();
            WriteLine($"不准确计数器， 结果{c.Count}");
            WriteLine("------------------------------");

            WriteLine("使用线程原子操作的计数器，开始");

            var c1=new CounterNoLock();
            t1=new Thread(()=>TestCounter(c1));
            t2 = new Thread(() => TestCounter(c1));
            t3 = new Thread(() => TestCounter(c1));

            t1.Start();
            t2.Start();
            t3.Start();
            t1.Join();
            t2.Join();
            t3.Join();
            WriteLine($"使用线程原子操作的计数器， 结果{c1.Count}");
            WriteLine("------------------------------");
        }

        static void TestCounter(CounterBase c)
        {
            for (int i = 0; i < 10000; i++)
            {
                c.Increment();
                c.Decrement();
            }
        }

    }

    class Counter:CounterBase
    {
        private int _count;
        public int Count => _count;
        //等同于
        //public int _count { get; private set; }

        public override void Increment()
        {
            _count++;
        }

        public override void Decrement()
        {
            _count--;
        }
    }

    class CounterNoLock:CounterBase
    {
        private int _count;
        public int Count => _count;

        public override void Increment()
        {
            Interlocked.Increment(ref _count);
        }

        public override void Decrement()
        {
            Interlocked.Decrement(ref _count);
        }
    }

    /// <summary>
    /// 计数器类，抽象类
    /// </summary>
    abstract class CounterBase
    {
        public abstract void Increment();

        public abstract void Decrement();
    }
}
